﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KylinORM.Utils;
using System.Data;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
using System.Data.Common;

namespace KylinORM.Data.SqlServer
{
    /// <summary>
    /// 数据访问类的SqlServer实现
    /// </summary>
    public class SqlServerHelperAdapter : IDataProvider
    {
        /// <summary>
        /// 创建SqlServerHelperAdapter的实例
        /// </summary>
        public SqlServerHelperAdapter()
        {
            this.ConnectionString = ConfigManager.DefaultDataServer;
        }

        #region 初始化

        /// <summary>
        /// 连接字符串
        /// </summary>
        public string ConnectionString
        {
            get { return SqlServerHelper.connectionString; }
            protected set { SqlServerHelper.connectionString = value; }
        }

        /// <summary>
        /// 超时时间
        /// </summary>
        public int CommandTimeout
        {
            get { return SqlServerHelper.commandTimeout; }
            protected set { SqlServerHelper.commandTimeout = value; }
        }

        /// <summary>
        /// 数据库类型
        /// </summary>
        public EDataProviderType ProviderType
        {
            get { return EDataProviderType.SqlServer; }
        }
        
        /// <summary>
        /// 创建数据库连接
        /// </summary>
        /// <returns></returns>
        public IDbConnection CreateConnection()
        {
            return new SqlConnection(this.ConnectionString);
        }

        /// <summary>
        /// 创建数据库命令
        /// </summary>
        /// <returns></returns>
        public IDbCommand CreateCommand(DataQuery query)
        {
            IDbCommand cmd = query.Command ?? this.CreateConnection().CreateCommand();

            cmd.CommandText = query.CommandText;
            cmd.CommandType = query.CommandType;
            cmd.CommandTimeout = this.CommandTimeout;
            cmd.Parameters.Clear();
            foreach (var parm in this.PrepareCommand(query.CommandText, query.Parameters))
                cmd.Parameters.Add(parm);

            return cmd;
        }
        /// <summary>
        /// 创建查询参数
        /// </summary>
        /// <param name="name">参数名称</param>
        /// <param name="value">参数值</param>
        /// <returns></returns>
        public DbParameter CreateParameter(string name, object value)
        {
            return new SqlParameter(name, value);
        }
        #endregion

        #region 格式化参数
        private static Regex queryParms = new Regex(@"(?<!@)@\w+", RegexOptions.Compiled);
        private SqlParameter[] PrepareCommand(string commandText, params object[] parameterValues)
        {
#if DEBUG
            System.Diagnostics.Debug.WriteLine(commandText);
#endif
            //if (parameterValues != null && parameterValues.FirstOrDefault() is SqlParameter)
            //    return parameterValues.Select(d => (SqlParameter)d).ToArray();
            if (parameterValues != null && parameterValues.Length > 0 && parameterValues[0] is SqlParameter)
            {
                List<SqlParameter> sqlParms = new List<SqlParameter>();
                foreach (SqlParameter parameterValue in parameterValues)
                        sqlParms.Add(parameterValue);
                return sqlParms.ToArray();
            }

            Dictionary<string, SqlParameter> parms = new Dictionary<string, SqlParameter>();
            if (parameterValues != null)
            {
                int index = 0;
                //循环给参数赋值
                foreach (Match mach in queryParms.Matches(commandText))
                {
                    if (parms.Keys.Contains(mach.Value))
                        continue;

                    parms.Add(mach.Value, new SqlParameter(mach.Value, parameterValues[index++]));
                }
            }
            return parms.Values.ToArray();
        }
        #endregion

        #region ExecuteData
        public DataRow ExecuteDataRow(DataQuery query)
        {
            return SqlServerHelper.ExecuteDataRow(this.CreateCommand(query));
        }

        public DataSet ExecuteDataSet(DataQuery query)
        {
            return SqlServerHelper.ExecuteDataSet(this.CreateCommand(query));
        }

        public DataTable ExecuteDataTable(DataQuery query)
        {
            return SqlServerHelper.ExecuteDataTable(this.CreateCommand(query));
        }
        #endregion

        #region ExecuteQuery
        public int ExecuteNonQuery(DataQuery query)
        {
            return SqlServerHelper.ExecuteNonQuery(this.CreateCommand(query));
        }

        public object ExecuteScalar(DataQuery query)
        {
            return SqlServerHelper.ExecuteScalar(this.CreateCommand(query));
        }
        #endregion
    }
}
